import markdown
from django.db import models
from django.utils.text import slugify
from django.utils.html import strip_tags
from markdown.extensions.toc import TocExtension

# Create your models here.

#  开发步骤
#  面向数据库的
#  以前 第一点事情设计数据库
#  code first  orm
#  第一个是定模型

#  需要哪些模型
#  用户
#  文章
#  分类
#  标签
#  评论

#  每个模型需要哪些个字段

#  用户 id 昵称 邮箱 密码
#  文章 id 分类 文章内容 作者(用户) 创建时间 阅读次数
#  分类 id 分类名称
#  标签 id 标签名称
#  评论 id 评论内容 谁评论的(用户) 创建时间
from django.db.models import CASCADE

from users.models import User


class Category(models.Model):
    name = models.CharField(max_length=32, unique=True, verbose_name='名称')
    comment = models.CharField(max_length=64, blank=True, verbose_name='类别描述')

    class Meta:
        verbose_name = '类别'
        verbose_name_plural = verbose_name

    # 定义能够供普通人看懂的代表模型的具体记录的内容
    def __str__(self):
        return self.name


class Tag(models.Model):
    name = models.CharField(max_length=32, verbose_name='名称')

    class Meta:
        verbose_name = '标签'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name


class Article(models.Model):
    # 文章 id 标题 分类 文章内容 作者(用户) 创建时间 修改时间 摘要 阅读次数
    title = models.CharField(max_length=64, verbose_name='标题')
    content = models.TextField(verbose_name='内容')
    # auto_now_add 会根据添加这条记录的时间去进行记录当前时间，后续通过orm修改数据不会改变
    created_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    # auto_now 会根据添加这条记录的时间去进行记录当前时间，后续通过orm修改数据会跟着改变
    modified_time = models.DateTimeField(auto_now=True, verbose_name='最近修改时间')
    excerpt = models.CharField(max_length=200, blank=True, verbose_name='摘要')
    views = models.IntegerField(default=0, verbose_name='浏览次数')
    author = models.ForeignKey(User, on_delete=CASCADE, verbose_name='作者')
    category = models.ForeignKey(Category, on_delete=CASCADE, verbose_name='类别')
    tags = models.ManyToManyField(Tag, verbose_name='标签')

    class Meta:  # Django约定的，不要改，改了就没用了，按照约定编程
        verbose_name = '文章'
        verbose_name_plural = verbose_name
        ordering = ['-created_time']

    def __str__(self):
        return self.title

    def save(self, *args, **kwargs):
        # md的文档变成网页的内容之后包含了大量的标签内容，
        # 我们去掉标签只保留文字，我们只要保留前128个字符就可以了
        if not self.excerpt:
            # 没有摘要才进行进一步的处理
            md = self.md_content()  # 得到的是md内容的html表现形式，实际是HMTL的代码
            self.excerpt = strip_tags(md)[:128]
        super(Article, self).save(*args, **kwargs)

    @staticmethod
    def get_md():
        return markdown.Markdown(
            extensions=[
                'markdown.extensions.extra',  # 基础拓展
                'markdown.extensions.codehilite',
                TocExtension(slugify=slugify)
            ]
        )

    def md_toc(self):
        md = self.get_md()
        md.convert(self.content)
        return md.toc

    def md_content(self):
        md = self.get_md()
        return md.convert(self.content)
        # markdown 文档
        # pip install markdown
        # return markdown.markdown(
        #     self.content,
        #     extensions=[
        #         'markdown.extensions.extra',  # 基础拓展
        #         'markdown.extensions.codehilite',
        #         'markdown.extensions.toc'
        #     ]
        # )
        # 实现代码高亮的两步
        # 1. 添加 'markdown.extensions.codehilite'
        # 2. pip install pygments

    # def comment_count(self):
    #     return Comment.objects.filter(article=self).count()

    def increase_views(self):
        self.views += 1
        self.save(update_fields=['views'])


#  评论 id 评论内容 谁评论的(用户) 创建时间

class Comment(models.Model):
    article = models.ForeignKey(Article, on_delete=CASCADE, verbose_name='文章')
    user = models.ForeignKey(User, on_delete=CASCADE, verbose_name='用户')
    content = models.TextField(verbose_name='内容')
    created_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')

    class Meta:
        verbose_name = '评论'
        verbose_name_plural = verbose_name
        ordering = ['-created_time']

    def __str__(self):
        return self.content

#  用户 id 昵称 邮箱 密码

# 怎么样添加昵称（怎么样去拓展用户模型）？
#  1. 使用first_name 这些实际我们用不到的字段来代替
#  2. 使用一个新的模型
# class WxUser(models.Model):
#     user = models.OneToOneField(User)
#     nickname = models.CharField(max_length=32, verbose_name='昵称')
#     phone = models.CharField(max_length=32, verbose_name='昵称')
# 3. 直接定义一个模型然后继承自AbstractUser，并且在配置文件中指定使用新定义的用户模型


# 用户模块，基于django已有模块的二次开发
